<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;

use App\Model\BotsModel;
use App\Model\OutTradeModel;
use App\Service\SteamService;

class CheckOutTrade extends Command
{
	/**
	 * The console command name.
	 *
	 * @var string
	 */
	protected $signature = 'check:outtrade';

	/**
	 * The console command description.
	 *
	 * @var string
	 */
	protected $description = '检查报价状态.';

	/**
	 * Create a new command instance.
	 *
	 * @return void
	 */
	public function __construct()
	{
		parent::__construct();
	}

	/**
	 * 获取待检查的报价状态
	 * @return array
	 */
	protected function getOutTradeByCheckAll()
	{
		return OutTradeModel::getOutTradeByCheckAll();
	}

	/**
	 * 获取机器人信息
	 * @param  int $botId 机器人ID
	 * @return array
	 */
	protected function getBotsInfoBybotId($botId)
	{
		return BotsModel::getBotsInfoBybotId($botId);
	}

	/**
	 * 修改报价状态
	 * @param  int $outTradeId 报价订单ID
	 * @param  int $tradeofferStatus 报价状态
	 * @return bool
	 */
	protected function updateOutTradeState($outTradeId, $tradeofferStatus)
	{
		return OutTradeModel::updateOutTradeState($outTradeId, $tradeofferStatus);
	}

	/**
	 * 多报价处理
	 * @return bool
	 */
	protected function checkTradeAll()
	{
		$trades = $this->getOutTradeByCheckAll();
		if (!$trades) {
			echo 'query waiting check for accept failed'."\r\n";
			return false;
		}

		foreach ($trades as $trade) {
			$res = $this->timeOutTrade($trade['out_trade_id'], $trade['tradeoffer_status'], $trade['updated_at']);
			if ($res) {
				echo 'query out trade timeout, out_trade_id: '.$trade['out_trade_id']."\r\n";
				continue;
			}

			$this->checkTrade($trade['bot_id'], $trade);
		}

		return true;
	}

	/**
	 * 报价超时处理
	 * @param  int $outTradeId 报价订单ID
	 * @param  int $tradeState 报价状态
	 * @param  int $updatedAt 报价修改时间
	 * @return bool
	 */
	protected function timeOutTrade($outTradeId, $tradeState, $updatedAt)
	{
		// 报价超时
		if ($tradeState == OutTradeModel::$tradeStatusMap['reading']) {

			if (strtotime($updatedAt) < (time() - 300)) {
				$res = $this->updateOutTradeState($outTradeId, OutTradeModel::$tradeStatusMap['time-out']);
				if (!$res) {
					echo 'update outtrade status failed, out_trade_id: '.$outTradeId."\r\n";
				}
				return true;
			}
		}

		return false;
	}

	/**
	 * 单报价处理
	 * @return bool
	 */
	protected function checkTrade($botId, array $trade)
	{
		$info = $this->getBotsInfoBybotId($botId);
		if (!$info) {
			echo 'query bots failed, botid: '.$botId."\r\n";
			return false;
		}

		$apiKey = $info['apikey'];
		$tradeofferId = $trade['tradeoffer_id'];

		$tradeoffer = SteamService::getInstance()->getTradeoffer($apiKey, $tradeofferId);
		if (!$tradeoffer) {
			echo 'query steam trade offer failed, tradeoffer_id:'.$trade['tradeoffer_id']."\r\n";
			return false;
		}
		$status = $tradeoffer['trade_offer_state'];

		// 报价已发起，已确认，超时取消报价
		if ($status == OutTradeModel::$tradeStatusMap['creating'] 
			|| $status == OutTradeModel::$tradeStatusMap['waiting']) {
			if (strtotime($trade['updated_at']) < (time() - 300)) {
				return $this->cancelTrade($apiKey, $tradeofferId, $trade['out_trade_id']);
			}
		}

		if ($trade['tradeoffer_status'] == $status) {
			echo 'trade offer status no change, tradeofferid:'.$tradeofferId.', status: '.$status."\r\n";
			return false;
		}

		$res = $this->updateOutTradeState($trade['out_trade_id'], $status);
		if (!$res) {
			echo 'update outtrade status failed, tradeofferid: '.$tradeofferId."\r\n";
			return false;
		}

		echo 'update outtrade status success, tradeofferid: '.$tradeofferId."\r\n";
		return true;
	}

	/**
	 * 取消报价
	 * @param string $apiKey
	 * @param string $tradeofferId 报价ID
	 * @param int $outTradeId 取回报价ID
	 * @return bool
	 */
	protected function cancelTrade($apiKey, $tradeofferId, $outTradeId)
	{
		$res1 = SteamService::getInstance()->cancelTradeById($apiKey, $tradeofferId);
		if (!$res1) {
			echo 'steam cancel trade offer failed, tradeofferid: '.$tradeofferId."\r\n";
			return false;
		}

		$res2 = $this->updateOutTradeState($outTradeId, OutTradeModel::$tradeStatusMap['cancel']);
		if (!$res2) {
			echo 'cancel trade offer failed, tradeofferid: '.$tradeofferId."\r\n";
			return false;
		}

		echo 'trade offer out of time, tradeofferid:'.$tradeofferId."\r\n";
		
		return true;
	}

	/**
	 * Execute the console command.
	 *
	 * @return mixed
	 */
	public function handle()
	{
		$this->checkTradeAll();
		echo '数据查询完毕!'."\r\n";
		return true;
	}
}